﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AppMain
{
    //当一个子弹size:vec3(1,1,1)沿X轴飞行,每帧移动1.5个单位

    //每帧计算新位置子弹表现位置  客户端只需要表达出位置信息就行了
    //那么第一帧的子弹size(1,1,1) pos(0,0,0) 第二帧size(1,1,1) pos(1.5f,0,0)

    //服务器每帧计算每帧子弹BOX位置 及大小 服务器要重新构建位置和BOX大小
    //那么第一帧的子弹size(1,1,1) pos(0,0,0) 第二帧size(1.5f,1,1) pos(1.25f,0,0)

    public enum Bullet_Status
    {
        Init,
        Loading,
        Running,
        Rmove,
    }

    public class BulletRole : BoxRole
    {
        public BulletRole(IAttrMap attrMap) : base(attrMap)
        {
        }

        public Bullet_Status Status = Bullet_Status.Init;
        private float passDistance = 0;
        public int TempId => this.AttrMap.getAttr<int>(RoleAttr.RoleTempId).Value;

        public long SceneUID => this.AttrMap.getAttr<long>(RoleAttr.SceneId).Value;

        float speed = 0;
        float distance = 0;
        Vec3 dir = Vec3.zero;
        Vec3 pos = Vec3.zero;
        Vec3 size = Vec3.zero;

        protected override void initMoveWidget()
        {

        }

        protected override void initialize()
        {
            base.initialize();
            pos = this.AttrMap.getAttr<Vec3>(RoleAttr.Position).Value;
            size = this.AttrMap.getAttr<Vec3>(RoleAttr.BoxSize).Value;
            this.box3D.updateSize(size.x, size.y, size.z);
            this.box3D.updatePos(pos.x, pos.y, pos.z);

            speed = this.AttrMap.getAttr<float>(RoleAttr.Speed).Value;
            distance = this.AttrMap.getAttr<float>(RoleAttr.Distance).Value;
            dir = this.AttrMap.getAttr<Vec3>(RoleAttr.Dir).Value;

            drawBox();
        }

        public override void tick(float frameTime)
        {
            float dirx = this.dir.x;//normalize
            float dirz = this.dir.z;//normalize
            float xMove = dirx * frameTime * speed;
            float zMove = dirz * frameTime * speed;
            //计算BOX
            float posX = pos.x;
            float posZ = pos.z;
            float sizeX = size.x;
            float sizeZ = size.z;
            passDistance += xMove;
            passDistance += zMove;
            float dis = Math.Abs(passDistance);
            bool arrive = dis > this.distance;
            if (arrive)
            {
                float sub = dis - this.distance;
                float percent = sub / this.distance;
                xMove *= percent;
                zMove *= percent;
                this.Status = Bullet_Status.Rmove;
            }

            float moveBoxPosX = xMove + posX;// (xMove + posX + posX) * 0.5f;
            float moveBoxPosZ = zMove + posZ;// //(zMove + posZ + posZ) * 0.5f;
            float moveBoxSizeX = sizeX;
            float moveBoxSizeZ = sizeZ;

            pos.x += xMove;
            pos.z += zMove;

            float xMoveAbs = Math.Abs(xMove);
            if (xMoveAbs > sizeX)
            {
                moveBoxSizeX = xMoveAbs;
                if (xMoveAbs > 0)
                {
                    moveBoxPosX = (sizeX + xMove) * 0.5f + posX;
                }
                else
                {
                    moveBoxPosX = (xMove - sizeX) * 0.5f + posX;
                }
            }
            float zMoveAbs = Math.Abs(zMove);
            if (zMoveAbs > sizeZ)
            {
                moveBoxSizeZ = zMoveAbs;
                if (zMoveAbs > 0)
                {
                    moveBoxPosZ = (sizeZ + zMove) * 0.5f + posZ;
                }
                else
                {
                    moveBoxPosZ = (zMove - sizeZ) * 0.5f + posZ;
                }
            }
            box3D.updateSize(moveBoxSizeX, box3D.sizeY, moveBoxSizeZ);
            box3D.updatePos(moveBoxPosX, box3D.posY, moveBoxPosZ);
            //Console.WriteLine(box3D.ToString());
            //碰撞检测 
            checkCollision();
            drawBox();
        }

        private void checkCollision()
        {
            //与场景中的实体检测碰撞
        }

        public override bool CanRemove => this.Status == Bullet_Status.Rmove;

        void drawBox()
        {
            BaseScene scene = SceneMgr.Instance.getScene<BaseScene>(SceneUID);
            if (scene != null)
            {
                pb.ServerBoxMsg msg = new pb.ServerBoxMsg();
                msg.pos = new pb.PBVector3();
                msg.pos.x = box3D.posX;
                msg.pos.y = box3D.posY;
                msg.pos.z = box3D.posZ;
                msg.size = new pb.PBVector3();
                msg.size.x = box3D.sizeX;
                msg.size.y = box3D.sizeY;
                msg.size.z = box3D.sizeZ;
                scene.broadCast(Cmd.ServerBoxMsg, msg);
            }
        }

    }
}
